package org.budo.graph.service.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.budo.support.slf4j.Slf4j;
import org.budo.support.spring.context.aware.BudoApplicationContextAware;
import org.budo.support.spring.util.SpringUtil;
import org.slf4j.Logger;
import org.springframework.context.ApplicationContext;

/**
 * @author limingwei
 */
public class GraphSpringUtil {
    private static final Logger log = Slf4j.getLogger();

    public static String writeSpringBeanResponse(String url) {
        BudoApplicationContextAware applicationContextAware = BudoApplicationContextAware.getInstance();
        if (null == applicationContextAware) {
            log.warn("#16 applicationContextAware is null");
            return "BudoApplicationContextAware is null";
        }

        ApplicationContext applicationContext = applicationContextAware.getApplicationContext();
        if (null == applicationContext) {
            log.warn("#16 applicationContext is null, applicationContextAware=" + applicationContextAware);
            return "applicationContext is null, applicationContextAware=" + applicationContextAware;
        }

        Map<String, Object> map = new HashMap<String, Object>();

        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            Object beanInstance = SpringUtil.getBean(applicationContext, beanName);
            map.put(beanName, beanInstance);
        }

        List<Entry<String, Object>> list = new ArrayList<Entry<String, Object>>(map.entrySet());
        Collections.sort(list, new Comparator<Entry<String, Object>>() {
            public int compare(Entry<String, Object> o1, Entry<String, Object> o2) {
                Object value1 = o1.getValue();
                String type1 = null == value1 ? Object.class.getName() : value1.getClass().getName();

                Object value2 = o2.getValue();
                String type2 = null == value2 ? Object.class.getName() : value2.getClass().getName();

                return type1.compareTo(type2);
            }
        });

        String response = "<pre>";
        int i = 1;
        for (Entry<String, Object> entry : list) {
            Object beanInstance = entry.getValue();

            Class<?> beanType = null == beanInstance ? null : beanInstance.getClass();
            String beanTypeName = null == beanType ? null : beanType.getName();
            String hexHashCode = null == beanInstance ? null : Integer.toHexString(beanInstance.hashCode());

            String key = entry.getKey();
            response += (i++) + ". " + beanTypeName + "@" + hexHashCode + "\t" + key + "\n";
        }
        return response + "</pre>";
    }
}